//////////////////////////////////////////////
// EnvironmentStrategy.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward decl -----------------------------

namespace nkScripts
{
	class Environment ;
	class Function ;
	class Namespace ;
	class Script ;
	class ScriptObjectReference ;
	class ScriptStrategy ;
	class UserType ;
}

/// Includes ---------------------------------

// nkScripts
#include "../Functions/FunctionDefines.h"

#include "../ExecutionResult.h"

// nkMemory
#include <NilkinsMemory/Containers/Buffer.h>
#include <NilkinsMemory/Containers/BufferView.h>

/// Class ------------------------------------

namespace nkScripts
{
	class EnvironmentStrategy
	{
		public :

			// Constructeur, destructeur
			EnvironmentStrategy (Environment* parentEnv) noexcept ;
			virtual ~EnvironmentStrategy () ;

			// Getters
			Environment* getParentEnv () const ;
			const ExecutionResult& getLastExecutionResult () const ;

			// Exécution
			virtual bool execute (const Script& script) = 0 ;
			virtual void requestGarbageCollection () = 0 ;
			virtual void shutdown () = 0 ;

			// Changement des vars
			virtual void setVar (nkMemory::StringView name, bool value) = 0 ;
			virtual void setVar (nkMemory::StringView name, int value) = 0 ;
			virtual void setVar (nkMemory::StringView name, float value) = 0 ;
			virtual void setVar (nkMemory::StringView name, double value) = 0 ;
			virtual void setVar (nkMemory::StringView name, nkMemory::StringView value) = 0 ;
			virtual void setVar (nkMemory::StringView name, const ScriptObjectReference& value) = 0 ;
			virtual void setObject (nkMemory::StringView name, nkMemory::StringView userTypeName, void* value) = 0 ;

			virtual bool isSet (nkMemory::StringView name) = 0 ;

			virtual bool getVar (nkMemory::StringView name, bool defaultValue) = 0 ;
			virtual int getVar (nkMemory::StringView name, int defaultValue) = 0 ;
			virtual float getVar (nkMemory::StringView name, float defaultValue) = 0 ;
			virtual double getVar (nkMemory::StringView name, double defaultValue) = 0 ;
			virtual nkMemory::StringView getVar (nkMemory::StringView name, nkMemory::StringView defaultValue) = 0 ;
			virtual ScriptObjectReference getVar (nkMemory::StringView name) = 0 ;
			virtual void* getObject (nkMemory::StringView name, nkMemory::StringView userTypeName) = 0 ;
			virtual ScriptObjectReference getScriptFunction (nkMemory::StringView name) = 0 ;

			// Fonctions
			virtual Function* setFunc (nkMemory::StringView name) = 0 ;

			// UserTypes
			virtual UserType* setUserType (nkMemory::StringView name) = 0 ;

			// Namespaces
			virtual Namespace* setNamespace (nkMemory::StringView name) = 0 ;

			// Call C++ -> Script
			virtual bool callScriptFunction (const ScriptObjectReference& reference, const DataStack& args, DataStack& expectedOutput) = 0 ;
			virtual nkMemory::Buffer serializeScriptObject (const ScriptObjectReference& reference, bool forwardUserDataOwnership) = 0 ;
			virtual ScriptObjectReference deserializeScriptObject (nkMemory::BufferView<unsigned char> object) = 0 ;

		protected :

			// Functions
			// Getters
			ScriptStrategy* _getStrategyFrom (const Script* script) ;

		protected :

			// Attributes
			// Parent environment
			Environment* _parentEnv ;
			// Erreur potentielles
			ExecutionResult _lastExecutionResult ;
	} ;
}
